#include "shortcutlineedit.h"

ShortcutLineEdit::ShortcutLineEdit(const ShortcutRec &id, QWidget *parent) : QLineEdit(parent), m_id(id)
{
    //当文字变化的时候判断是否有效，离开的时候在注册快捷键
    connect(this, &QLineEdit::textChanged, this, &ShortcutLineEdit::isAvailableShortcut);
}

void ShortcutLineEdit::keyPressEvent(QKeyEvent *event)
{
    const quint32 WIN_KEY_SVANCODE = 133;
    if(event->nativeScanCode() == WIN_KEY_SVANCODE){
        handleMetaKey(event);
        return;
    }
    // 组合键字符串
    QString shortcut;
    if ( event->modifiers() & Qt::ControlModifier ) {
        shortcut.append( "+Ctrl" );
    }
    if ( event->modifiers() & Qt::MetaModifier) {
        shortcut.append( "+Meta" );
    }
    if ( event->modifiers() & Qt::ShiftModifier ) {
        shortcut.append( "+Shift" );
    }
    if ( event->modifiers() & Qt::AltModifier ) {
        shortcut.append( "+Alt" );
    }

    int key = event->key();
    if (key != Qt::Key_Control && key != Qt::Key_Shift && key != Qt::Key_Alt && key != Qt::Key_Meta) {
        shortcut.append( "+" + QKeySequence(key).toString() );
    }

    if ( shortcut.startsWith( "+" ) == true ) {
        shortcut.remove( 0, 1 );
    }

    setText(shortcut);
    currentText = shortcut;

    event->accept();
}

void ShortcutLineEdit::focusOutEvent(QFocusEvent *event)
{
    onTextChanged(currentText);
    isAvailable = true;

    QLineEdit::focusOutEvent(event);

}

void ShortcutLineEdit::paintEvent(QPaintEvent *event)
{
    QLineEdit::paintEvent(event); // 先调用基类的绘制

    if (!isAvailable) {
        QPainter painter(this);
        painter.setPen(Qt::red);

        QFontMetrics metrics(font());
        int textWidth = metrics.width(text);
        int x = width() - textWidth - 5; // 5 是左侧的边距
        int textHeight = metrics.height();
        int y = (height() + textHeight) / 2 - metrics.descent(); // 计算基线位置
        painter.drawText(x, y, text);
    }
}

void ShortcutLineEdit::onTextChanged(const QString &newText)
{
    qDebug()<<"ShortcutLineEdit::onTextChanged 输入值"<<newText ;
    isAvailable = isAvailableShortcut(newText);
    if(isAvailable){    //有效
        qDebug()<<"ShortcutLineEdit::onTextChanged 输入值 有效" ;
        if(Global::listShortcut.contains(preShortcut)){
            Global::listShortcut.removeOne(preShortcut);
        }
        Global::listShortcut.append(newText);
        preShortcut = newText;
        //注册快捷键
        shortcutChanged(m_id, newText);
        //写入文件
        ConfigHandler().setShortcut(m_id, newText);
    }else{
        setText(preShortcut);
    }
}

bool ShortcutLineEdit::isAvailableShortcut(QString shortcut)
{
    isAvailable = true;
    KeyStatus = 1;
    QKeySequence key = QKeySequence(shortcut);

    if (key.toString().isEmpty()) {
        isAvailable = false;
        KeyStatus = 0;
    }else{

        if(preShortcut == shortcut){ //上次的快捷键则返回
            return isAvailable;
        }

        if(Global::listShortcut.contains(shortcut)          //自己本身
//                || conflictWithGlobalShortcuts(key)       //全局快捷键检测输入不了也不用检测
                || conflictWithStandardShortcuts(key)){     //标准快捷键
            qDebug()<<"热键冲突："<<shortcut
                   <<Global::listShortcut.contains(shortcut)
//                   << conflictWithGlobalShortcuts(key)
                   << conflictWithStandardShortcuts(key)
                   << Global::listShortcut;
            isAvailable = false;
            KeyStatus = 2;
        }
    }

    return isAvailable;
}

bool ShortcutLineEdit::conflictWithGlobalShortcuts(const QKeySequence &seq)
{
    if (!KGlobalAccel::isGlobalShortcutAvailable(seq)) {
        QList<KGlobalShortcutInfo> conflicts = KGlobalAccel::getGlobalShortcutsByKey(seq);
        bool isConflictWithScreencap = true;
        foreach (const KGlobalShortcutInfo &info, conflicts) {
            if(info.friendlyName() == "唤醒录屏"){
                continue;
            }
            isConflictWithScreencap = false;
            qDebug() << "Conflict with KGlobalAccel : " << info.friendlyName();
        }
        if(!isConflictWithScreencap){
            return true;
        }

    }
    return false;
}

bool ShortcutLineEdit::conflictWithStandardShortcuts(const QKeySequence &seq)
{
    KStandardShortcut::StandardShortcut ssc = KStandardShortcut::find(seq);
    if (ssc != KStandardShortcut::AccelNone) {
        QString conflictValue = KStandardShortcut::label(ssc);
        QString conflictKey = seq.toString();
        qDebug() << "conflict With Standard Shortcuts ：" << conflictKey << conflictValue;
        return true;
    }
    return false;
}

QString ShortcutLineEdit::keyToLib(QString key)
{
    if (key.contains("+")) {
        QStringList keys = key.split("+");
        if (keys.count() == 2) {
            QString lower = keys.at(1);
            QString keyToLib = "<" + keys.at(0) + ">" + lower.toLower();

            return keyToLib;
        } else if (keys.count() == 3) {
            QString lower = keys.at(2);
            QString keyToLib = "<" + keys.at(0) + ">" + "<" + keys.at(1) + ">" + lower.toLower();

            return keyToLib;
        } else if (keys.count() == 4) {
            QString lower = keys.at(3);
            QString keyToLib = "<" + keys.at(0) + ">" + "<" + keys.at(1) + ">" + "<" + keys.at(2) + ">" + lower.toLower();

            return keyToLib;
        }
    }
        return key;
}

void ShortcutLineEdit::handleMetaKey(QKeyEvent *event){
    QString shortcut;
    const quint32 WIN_KEY_SVANCODE = 133;
    if(event->type() == QEvent::KeyPress){
        shortcut = "Meta";
        if ( event->modifiers() & Qt::ControlModifier ) {
            shortcut.append( "+Ctrl" );
        }
        if ( event->modifiers() & Qt::ShiftModifier ) {
            shortcut.append( "+Shift" );
        }
        if ( event->modifiers() & Qt::AltModifier ) {
            shortcut.append( "+Alt" );
        }

        int key = event->key();
        if (key != Qt::Key_Control && key != Qt::Key_Shift && key != Qt::Key_Alt && key != Qt::Key_Meta && event->nativeScanCode() != WIN_KEY_SVANCODE) {
            shortcut.append( "+" + QKeySequence(key).toString() );
        }

        if ( shortcut.startsWith( "+" ) == true ) {
            shortcut.remove( 0, 1 );
        }

        setText(shortcut);
        currentText = shortcut;
    }
    event->accept();
}
